package com.bhf.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bhf.constant.Constants;
import com.bhf.core.CustomIdGenerator;
import com.bhf.utils.*;
import lombok.Data;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author pwq
 */
@RestController
@RequestMapping("/es")
public class ElasticsearchController {

    @Resource
    private ElasticsearchUtil elasticsearch;
    @Resource
    private RestHighLevelClient client;

    public String url = "https://www.ximalaya.com/revision/category/queryCategoryPageAlbums?category=minnanyu&subcategory=&meta=&sort=0&perPage=30&page=";

    @GetMapping("/add/{page}")
    public RestResult<Object> add(@PathVariable("page") String page) throws IOException {
        for (int i = 1; i < 10; i++) {
            String s = HttpClientUtil.get(url + i);
            JSONObject data = (JSONObject) JSON.parseObject(s).get("data");
            String albums = data.get("albums").toString();
            List<Albums> albums1 = JSONArray.parseArray(albums, Albums.class);
            BulkRequest request = Requests.bulkRequest();
            albums1.forEach(e -> {
                request.add(new IndexRequest(Constants.BHF_DATA_INDEX).id(String.valueOf(new CustomIdGenerator().nextId(3))).source(EntityUtil.beanToMap(e)));
            });
            final BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
        }
        return RestResultUtils.success(true);
    }


    @GetMapping("/delete/{id}")
    public RestResult<Boolean> delete(@PathVariable("id") Long id) throws IOException {
        return RestResultUtils.success(elasticsearch.delete(Constants.BHF_DATA_INDEX, "vipType", id));
    }

    @GetMapping("/deleteOrAdd/{index}")
    public RestResult<Boolean> deleteOrAdd(@PathVariable("index") String index) throws IOException {
        return RestResultUtils.success(elasticsearch.index(Constants.BHF_DATA_INDEX, 3, 0, Arrays.asList(".bianhaifang", ".es_bianhaifang")));
    }

    @GetMapping("/search/{keywords}")
    public RestResult<List<Map<String, Object>>> searchQuery(@PathVariable("keywords") String keywords) throws IOException {
        SearchRequest request = new SearchRequest(Constants.BHF_DATA_INDEX);
        final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.timeout(TimeValue.timeValueSeconds(10));
        final QueryBuilder queryBuilder = new MatchQueryBuilder("title", keywords).analyzer("ik_max_word");
        searchSourceBuilder.query(queryBuilder);
        final HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<span color='red'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.field("title");
        searchSourceBuilder.highlighter(highlightBuilder);

        searchSourceBuilder.from(1);
        searchSourceBuilder.size(20);

        request.source(searchSourceBuilder);
        final SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        final SearchHits hits = search.getHits();
        List<Map<String, Object>> results = new ArrayList<>();
        for (SearchHit hit : hits.getHits()) {
            final Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            final Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            for (Map.Entry<String, HighlightField> entry : highlightFields.entrySet()) {
                final Text[] fragments = highlightFields.get(entry.getKey()).getFragments();
                StringBuilder title = new StringBuilder();
                for (Text text : fragments) {
                    title.append(text);
                }
                sourceAsMap.put(entry.getKey(), title.toString());
            }
            results.add(sourceAsMap);
        }
        return RestResultUtils.success(results);
    }
}

@Data
class Albums implements Serializable {
    private static final long serialVersionUID = 9010327987915793609L;
    private String anchorName, title, coverPath;
    private Integer vipType, trackCount;
    private long playCount;
    private LocalDateTime createTime = LocalDateTime.now();
}
